#include "SpaceShip.h"
#include "Bullet.h"
SpaceShip::SpaceShip()
{
	this->hitpoints = SpaceShipBaseHitpoints;
	//this->collider = c;
	rateOfFire = 5;
	bulletCounter = 0;
}

SpaceShip::~SpaceShip(void)
{
	GlobalDebug::GetInstance()->DbgOut("Deleting SpaceShip");
}

bool SpaceShip::IsDead(){
	int hp = 10;// = this->hitpoints
	if(hp <= 0)
		return true;
	else
		return false;
}

float SpaceShip::GetGunPositionX()
{

	return PhysicsCalculator::CalcNewXValue(
		this->mobile->GetValue(PhysicsComponent::Rotation),
		this->renderable->GetCenter().x, 
		30.0f);
}

float SpaceShip::GetGunPositionY()
{
	return PhysicsCalculator::CalcNewYValue(
		this->mobile->GetValue(PhysicsComponent::Rotation),
		this->renderable->GetCenter().y,
		30.0f);
}

void SpaceShip::SetHitpoints(int value)
{
	this->hitpoints = value;
}

int SpaceShip::GetHitpoints()
{
	return this->hitpoints;
}

GameObject* SpaceShip::FirePrimary()
{
	// TODO: refactor with some sort of weapon class
	// TODO: srsly, do this now
	if(bulletCounter == 0)
	{
		// we can fire
		this->bulletCounter = rateOfFire;
	}
	else
	{
		return NULL;
	}
	
	int nextID = IDFactory::GetNextID();

	// TODO:  this sucks, fix it
		Mobile* m = new Mobile();
		GameObject* bullet = new Bullet();
		Collider* c = new Collider();

	m->SetValue(PhysicsComponent::PositionX, GetGunPositionX());
	m->SetValue(PhysicsComponent::PositionY, GetGunPositionY());
	m->SetValue(PhysicsComponent::GeneralVelocity, 12);
	m->SetValue(
		PhysicsComponent::Rotation, 
		mobile->GetValue(PhysicsComponent::Rotation));
	//m->SetOwner(bullet);
	
	
	
	c->SetRadius(1);
	
	
	bullet->SetID(nextID);
	bullet->SetController(this->owningController);
	m->SetCollider(c);
	bullet->SetMobile(m);
	bullet->SetParent(this);
	return bullet;
}

bool SpaceShip::Update()
{
	if(bulletCounter > 0)
	{
		bulletCounter--;
	}
	return true;
}

void SpaceShip::PreProcessMessages()
{
	this->mobile->SetValue(PhysicsComponent::GeneralVelocity, 0);

}
void SpaceShip::ProcessMessage(Message* msg)
{
	// TODO: massive OCP violation- these things should have their own message handlers
	if(msg->GetMessageType() == MessageType::USER_INPUT)
	{
		int msgContent = msg->GetMessageContent();
		if(msgContent == GameAction::MOVE_UP)
		{
			this->mobile->SetValue(PhysicsComponent::GeneralVelocity, spaceShipVelocity);
		}
		else if(msgContent == GameAction::MOVE_RIGHT)
		{
			float theta = this->mobile->GetValue(PhysicsComponent::Rotation);
			theta += _turnstep;
			if(theta > 1)
				theta -= 1;
			mobile->SetValue(PhysicsComponent::Rotation, theta);
		}
		else if(msgContent == GameAction::MOVE_LEFT)
		{
			float theta = this->mobile->GetValue(PhysicsComponent::Rotation);
			theta -= _turnstep;
			if(theta <= 0)
				theta += 1;
			mobile->SetValue(PhysicsComponent::Rotation, theta);			
		}
		else if(msgContent == GameAction::FIRE_PRIMARY)
		{
			GameObject* obj = this->FirePrimary();
			// may not fire every time so check return value
			if(obj != NULL)
			{
				Message* message = new Message(MessageType::GAME_OBJECT_ACTION, MessageContent::CREATE_OBJECT, (void*)obj);
				assert(owningController != NULL);
				owningController->PassMessage(message);
			}
		}
		
	}
	else if(msg->GetMessageType() == MessageType::GAME_OBJECT_ACTION)
	{
		if(msg->GetMessageContent() == MessageContent::COLLISION)
		{
			GameObject* objectICollidedWith = (GameObject*)msg->GetExtended();

		}
	}
	delete msg;
	
}
void SpaceShip::PostProcessMessages()
{

}

void SpaceShip::PreGetRenderable()
{
	assert(this->renderable != NULL);
	float x, y, r;
	x = mobile->GetValue(PhysicsComponent::PositionX);
	y = mobile->GetValue(PhysicsComponent::PositionY);
	r = mobile->GetValue(PhysicsComponent::Rotation) * 2 * PI;
	renderable->SetPosition(x, y);
	renderable->SetRotation(r);
}

ObjectType SpaceShip::GetType()
{
	return ObjectType::SPACESHIP;
}